//
// Created by lymk on 2022/3/13.
//

#include "PhongShader.h"

VertexOut PhongShader::VertexShader(VertexIn vertexIn) {
    VertexOut vertexOut;
    vertexOut.color = vertexIn.color;
    vertexOut.worldPos = uniform->model * vertexIn.pos;
    vertexOut.pos = uniform->perspective * uniform->viewPort* vertexOut.worldPos;
    vertexOut.texCoord = vertexIn.texCoord;
    glm::mat4 inv = uniform->model;
    inv = glm::inverse(inv);
    inv = glm::transpose(inv);
    glm::vec4 tmp = glm::vec4(vertexIn.normal,0.f);
    tmp = inv*tmp;
    //tmp =  tmp;
    //tmp = tmp/tmp.w;
    vertexOut.normal = tmp;
    return vertexOut;
}

glm::vec4 PhongShader::FragmentShader(VertexOut vertexOut) {
    glm::vec3 finalColor = {0.f,0.f,0.f};
    glm::vec3 originColor = vertexOut.color;
    glm::vec4 viewPos = {-1,1,0,1.f};
    float ambient = 0.1;
    float diffuse = 0.f;
    float spec = 0.f;
    float specularStrength = 0.2;
    for(int i=0;i<uniform->lights.size();i++){
        glm::vec3 lightDir = glm::vec4(uniform->lights[i].Position,1.f) - vertexOut.worldPos;
        lightDir = glm::normalize(lightDir);
        vertexOut.normal = glm::normalize(vertexOut.normal);
        float tmp = fmax(0.3*(uniform->lights[i].intensity * glm::dot(vertexOut.normal,lightDir)),0.f);
        diffuse+=tmp;

        glm::vec3 viewDir = viewPos - vertexOut.worldPos;
        glm::vec3 H = lightDir + viewDir;
        H = glm::normalize(H);
        viewDir = glm::normalize(viewDir);
        spec = glm::pow(glm::max(glm::dot(vertexOut.normal,H),0.f),32);
        spec = spec * specularStrength;
    }

    finalColor = (diffuse + ambient + spec)*originColor;
    return {finalColor,1.f};
}

PhongShader::PhongShader() {
    uniform = new Uniform();
}
